package com.plus.controller;


import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import com.plus.common.R;
import com.plus.utils.Func;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.plus.entity.User;
import com.plus.dto.UserDTO;
import com.plus.service.IUserService;

/**
 * 用户表 控制器
 *
 * @author ht
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/api/user")
@Api(value = "/api/user", tags = "用户表相关接口")
public class UserController {

	@Autowired
	private IUserService userService;


	@Autowired
	@Qualifier(value = "cacheManagertwo")
	private CacheManager cacheManager;


	/**
	 * 验证cache添加
	 */
	@GetMapping("/testCacheAdd")
	public R testCacheAdd() {

		Cache cache = cacheManager.getCache("cacheManagertwo");
		Map<String,Object> map = new HashMap<>();
		map.put("id",1);
		map.put("name","test");
		map.put("age",30);

		cache.put("user",map);

		return R.data(map);
	}

	/**
	 * 验证cache获取
	 */
	@GetMapping("/testCacheGet")
	public R testCacheGet() {

		Cache cache = cacheManager.getCache("cacheManagertwo");

		Map<String,Object> map = cache.get("user",Map.class);

		return R.data(map);
	}

	/**
	 * 分页 用户表
	 * Cacheable: @Cacheble注解表示这个方法有了缓存的功能，方法的返回值会被缓存下来，下一次调用该方法前，会去检查是否缓存中已经有值，如果有就直接返回，不调用方法
	 */
	@Cacheable(cacheNames = "userpage",key = "#keyId")
	@GetMapping("/page")
	@ApiOperation(value = "分页", notes = "传入user")
	public R<IPage<User>> page(UserDTO dto,String keyId) {
		IPage<User> pages = userService.page(dto);
		return R.data(pages);
	}

	/**
	 * 不分页 用户表
	 * Cacheable: @Cacheble注解表示这个方法有了缓存的功能，方法的返回值会被缓存下来，下一次调用该方法前，会去检查是否缓存中已经有值，如果有就直接返回，不调用方法
	 *
	 * 注意key是必传的，否则会报错
	 *
	 * http://localhost:8899/api/user/page?keyId=2
	 */
	@Cacheable(cacheNames = "user",key = "#keyId")
	@GetMapping("/list")
	@ApiOperation(value = "不分页", notes = "传入user")
	public R<List<User>> list(UserDTO dto,String keyId) {
		List<User> list = userService.list(dto);
		return R.data(list);
	}

	/**
	 * 修改 用户表
	 *
	 * @CacheEvict: @CacheEvict注解的方法，会清空指定缓存。一般用在更新或者删除的方法上。
	 *
	 * key必须和查询的一样清缓存才能生效
	 *
	 */
	@CacheEvict(cacheNames = "user",key = "#keyId")
	@GetMapping("/update")
	@ApiOperation(value = "修改", notes = "传入user")
	public R update(UserDTO dto,String keyId) {
		return R.data(userService.updateById(dto));
	}


	/**
	 * 新增 用户表
	 * @CachePut : @CachePut注解的方法，保证方法被调用，又希望结果被缓存。会把方法的返回值put到缓存里面缓存起来。它通常用在新增方法上。
	 * key必须和查询的一样清缓存才能生效
	 *
	 * http://localhost:8899/api/user/save?userName=%E5%85%AD1%E8%80%81%E5%B8%88&keyId=2
	 */
	@CachePut(cacheNames = "user",key = "#keyId")
	@GetMapping("/save")
	@ApiOperation(value = "新增", notes = "传入user")
	public R save(UserDTO dto,String keyId) {
		return R.data(userService.save(dto));
	}


	/**
	 * 删除 用户表
	 * @CachePut : @CachePut注解的方法，保证方法被调用，又希望结果被缓存。会把方法的返回值put到缓存里面缓存起来。它通常用在新增方法上。
	 */
	@CacheEvict(cacheNames = "user",key = "#keyId")
	@DeleteMapping("/remove")
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids,String keyId) {
		return R.data(userService.deleteLogic(Func.toIntList(ids)));
	}

	/**
	 * 详情
	 */
	@PostMapping("/detail")
	@ApiOperation(value = "详情", notes = "传入user")
	public R<User> detail(UserDTO dto) {
		User detail = userService.getOne(dto);
		return R.data(detail);
	}












}
